/*================================================================
 *   Copyright (C) 2019 hqyj Ltd. All rights reserved.
 *   
 *   文件名称：server.c
 *   创 建 者：LYang
 *   创建日期：2020年4月16日
 *   描    述：
 *
 ================================================================*/


#include "net.h"


int main(int argc, char *argv[])
{
	if(argc < 2){
		printf("pls input %s <port>\n",argv[0]);
		exit(1);
	}

	int sockfd;
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd <0){
		perror("sock");
		exit(1);
	}
	puts("socket");
	int reuse = 0x01;
	if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(int)) < 0)
	{
		perror("setsockopt error");
		close(sockfd);
		exit(1); 
	}

	struct sockaddr_in serveraddr= {
		.sin_family = AF_INET,
		.sin_port   = htons(atoi(argv[1])),
		.sin_addr.s_addr = htonl(INADDR_ANY),
	};
	socklen_t addrlen = sizeof(serveraddr);

	struct sockaddr_in clientaddr;
	socklen_t clientlen = sizeof(clientaddr);
	
	if(bind(sockfd,(struct sockaddr*)&serveraddr,addrlen)<0){
		perror("bind");
		exit(1);
	}
	puts("bind ok");

	if(listen(sockfd,5)<0){
		perror("listen ");
		exit(1);
	}
	puts("listen ok");

	int acceptfd;
	char buf[64]={0};

	fd_set readfs,temp;
	FD_ZERO(&readfs);
	FD_ZERO(&temp);
	FD_SET(sockfd,&readfs);
	FD_SET(0,&readfs);

	int maxfd;
	maxfd = sockfd;
	int val,i;

	while(1)
	{
		temp = readfs;
		val = select(maxfd+1,&temp,NULL,NULL,NULL);
		if(val <0){
			perror("select");
			exit(1);
		}
		for(i=0;i<maxfd+1;i++)
		{
			if(FD_ISSET(i,&temp))
			{
				if(0 == i){
					bzero(buf,sizeof(buf));
					fgets(buf,sizeof(buf),stdin);
					if(!strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))){
						puts("server is exit!");
						return 0;
					}
				}
				else if(i == sockfd)
				{
					acceptfd = accept(sockfd,(struct sockaddr*)&clientaddr,&clientlen);
					if(acceptfd<0){
						perror("accept.");	
						exit(1);
					}

					printf("client ip:%s port:%d\n",
							(char*)inet_ntoa(clientaddr.sin_addr),
							ntohs(clientaddr.sin_port));

					FD_SET(acceptfd,&readfs);
					maxfd = (maxfd >acceptfd)?maxfd:acceptfd; 
				}
				else {
					ssize_t sendbytes;
					if(buf[0]!=0){
						send(i,buf,sizeof(buf),0);
						bzero(buf,sizeof(buf));
					}
					ssize_t recvbytes;
					recvbytes = recv(i,buf,sizeof(buf),0);
					if(recvbytes < 0){
						FD_CLR(i,&readfs);
						close(i);
						perror("recv failed.");
						continue;
					}
					else if( 0 == recvbytes){
						printf("client %d exit\n",i);
						FD_CLR(i,&readfs);
						close(i);
						continue;
					}
					else{
						printf("recv : %s\n",buf);
						bzero(buf,sizeof(buf));

					}
				}
			}
		}
	}
	close(sockfd);
	return 0;
}

